package com.zk.api;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;

import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.zk.api.export.ExportDoc;
import com.zk.api.git.GitService;
import com.zk.api.model.ClassModel;
import com.zk.api.model.MethodModel;
import com.zk.api.model.ParamModel;
import com.zk.api.parser.Parser;
/**
 * <控制器>
 * 
 * @author 0380009081
 * @version 1.0
 */
@RestController
@RequestMapping("interface")
public class Controller {

	@Autowired
	RestTemplate httpService;

	@Autowired
	GitService gitService;

	@Autowired
	Parser parser;

	@Value("${git.dir}")
	private String dir;

	/**
	 * <自动从git上拉代码到本地>
	 * 
	 * @param TbaseUrl  git地址
	 * @param Tdir      本地地址
	 * @param Tuser     用户名
	 * @param Tpass     密码
	 * @param Tbranch   分支
	 * @param Trevision 版本
	 * @return @
	 */
	@GetMapping("code/pull")
	int codePull(String TbaseUrl, String Tdir, String Tuser, String Tpass, String Tbranch, String Trevision) {
		return gitService.getGitConfigPull();
	}

	/**
	 * <提交>
	 * 
	 * @param filed 文件類容
	 * @param type  类型 path,git,text
	 * @return
	 */
	@PostMapping("commit")
	List<ClassModel> commit(@RequestParam String filed, @RequestParam String type) {
		if ("path".equals(type)) {
			return parser.startBuild(new File(filed));
		} else if ("git".equals(type)) {
			Properties proper = new Properties();
			try {
				proper.load(new StringReader(filed));
				return parser.startBuild(proper.getProperty("git.baseUrl"), proper.getProperty("git.dir"), proper.getProperty("git.user"), proper.getProperty("git.pass"),proper.getProperty("git.branch"), proper.getProperty("git.revision"));
			} catch (IOException e) {
				e.printStackTrace();
			}
			return new ArrayList<ClassModel>();
		} else {
			return parser.startBuild(Arrays.asList(filed));
		}
	}

	/**
	 * <示例接口>
	 * 
	 * @param id 文档id
	 * @return
	 */
	@RequestMapping(value = "download/{id}", method = RequestMethod.DELETE)
	public int download(@PathVariable Integer id) {
		return id;
	}

	/**
	 * <示例接口>
	 * 
	 * @param id 文档id
	 * @return
	 */
	@GetMapping("download1")
	public int download1(@RequestParam(required = true, defaultValue = "10") Integer id) {
		return id;
	}

	@PostMapping("download")
	public void download(@RequestParam String model, HttpServletResponse response) throws Exception {
		List<ClassModel> models = JSONObject.parseArray(model, ClassModel.class);
		ExportDoc maker = new ExportDoc("UTF-8");
		try {
			HashMap<String, Object> m = new HashMap<String, Object>();
			m.put("clazzs", ExportDoc.convertNullToStr(models));
			// maker.exportDoc("C:\\Users\\0380009081\\Desktop\\Freemarket.doc",
			// "model_xml.ftl",m);
			File file = new File("/Freemarket.doc");
			FileOutputStream fos = new FileOutputStream(file);
			maker.exportDoc(fos, "model_xml.ftl", m);
			response.setContentType("application/force-download");// 设置强制下载不打开
			response.addHeader("Content-Disposition", "attachment;fileName=" + "model.doc");// 设置文件名
			byte[] buffer = new byte[1024];
			FileInputStream fis = null;
			BufferedInputStream bis = null;
			try {
				fis = new FileInputStream(file);
				bis = new BufferedInputStream(fis);
				OutputStream os = response.getOutputStream();
				int i = bis.read(buffer);
				while (i != -1) {
					os.write(buffer, 0, i);
					i = bis.read(buffer);
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new MyErrorException("系统错误，" + e.getMessage());
			} finally {
				if (bis != null) {
					try {
						bis.close();
					} catch (IOException e) {
						e.printStackTrace();
						throw new MyErrorException("系统错误，" + e.getMessage());
					}
				}
				if (fis != null) {
					try {
						fis.close();
					} catch (IOException e) {
						e.printStackTrace();
						throw new MyErrorException("系统错误，" + e.getMessage());
					}
				}
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		// throw new Exception("未开通");
		// return models;
	}

	/**
	 * <接口自动测试>
	 * 
	 * @param methods 方法
	 * @param header  请求头，cookie
	 * @param rootUrl ip和端口号
	 * @return
	 */
	@SuppressWarnings("unchecked")
	@PostMapping("test")
	public List<MethodModel> test(String methods, String header, String rootUrl) {
//		String[] paramType1 = {"byte", "short", "int", "long", "float", "double", "boolean","char"};
//		String[] paramType2 = {"Byte", "Short", "Integer", "Long", "Float", "Double", "Boolean","Character","Object"};
//		String[] paramType3 = {"List", "Map"};
		Map<String, String> headerMap = JSON.parseObject(header, HashMap.class);
		List<MethodModel> mets = JSON.parseArray(methods, MethodModel.class);
		if (methods != null) {
			for (MethodModel met : mets) {
				long start = System.currentTimeMillis();
				if (met.getMethodType() == null) {
					met.setMethodRunstatus("错误");
					met.setMethodRunresult("未知的请求类型");
					continue;
				}
				HttpHeaders headers = new HttpHeaders();
				if (header != null) {
					for (Entry<String, String> entry : headerMap.entrySet()) {
						headers.add(entry.getKey(), entry.getValue());
					}
				}
				switch (met.getMethodType()) {
				case "POST": {
					headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
					headers.add("Accept", MediaType.APPLICATION_JSON.toString());
					if (met.getMethodHttpHeader() != null) {
						for (Entry<String, String> entry : met.getMethodHttpHeader().entrySet()) {
							headers.add(entry.getKey(), entry.getValue());
						}
					}
					// 添加参数
					MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
					for (ParamModel par : met.getMethodParam()) {
						if (met.getMethodUrl().indexOf("{" + par.getParamName() + "}") != -1) {
							met.setMethodRealUrl(met.getMethodUrl().replaceAll("\\{" + par.getParamName() + "\\}",
									par.getParamValue() + ""));
						} else {
							if (par.getParamType() != null && par.getParamType().equals("Integer")) {
								map.put(par.getParamName(), par.getParamValue() == null ? null
										: Arrays.asList(Integer.parseInt("" + par.getParamValue())));
							} else if (par.getParamType() != null && par.getParamType().equals("String")) {
								map.put(par.getParamName(),
										par.getParamValue() == null ? null : Arrays.asList("" + par.getParamValue()));
							} else
								map.put(par.getParamName(),
										par.getParamValue() == null ? null : Arrays.asList(par.getParamValue()));
						}

					}
					HttpEntity<Object> formEntity = new HttpEntity<Object>(map, headers);
					try {
						//met.setMethodRealUrl(rootUrl + met.getMethodUrl());
						ResponseEntity<String> result = httpService.exchange(rootUrl+met.getMethodRealUrl(), HttpMethod.POST,
								formEntity, String.class);
						met.setMethodRunresult(result.getBody());
						met.setMethodRunstatus("" + result.getStatusCode());
					} catch (Exception e) {
						e.printStackTrace();
						// 捕捉HTTP异常
						met.setMethodRunresult(e.getMessage());
						met.setMethodRunstatus("" + 500);
					}
					break;
				}
				case "GET": {
					MediaType type = MediaType.parseMediaType("application/json; charset=UTF-8");
					headers.setContentType(type);
					headers.add("Accept", MediaType.APPLICATION_JSON.toString());
					if (met.getMethodHttpHeader() != null) {
						for (Entry<String, String> entry : met.getMethodHttpHeader().entrySet()) {
							headers.add(entry.getKey(), entry.getValue());
						}
					}
					String param = "";
					if (met.getMethodParam().size() > 0) {
						param = "?";
						for (ParamModel par : met.getMethodParam()) {
							if (met.getMethodUrl().indexOf("{" + par.getParamName() + "}") != -1) {
								met.setMethodRealUrl(met.getMethodUrl().replaceAll("\\{" + par.getParamName() + "\\}",
										par.getParamValue() + ""));
							} else {
								param += par.getParamName() + "="
										+ (par.getParamValue() == null ? "" : par.getParamValue()) + "&";
							}
						}
						param = param.substring(0, param.length() - 1);
					}
					HttpEntity<String> formEntity = new HttpEntity<String>(null, headers);
					try {
						//met.setMethodRealUrl(rootUrl + met.getMethodUrl() + param);
						ResponseEntity<String> result = httpService.exchange(rootUrl+met.getMethodRealUrl(), HttpMethod.GET,
								formEntity, String.class);
						met.setMethodRunresult(result.getBody());
						met.setMethodRunstatus("" + result.getStatusCode());
					} catch (Exception e) {
						e.printStackTrace();
						// 捕捉HTTP异常
						met.setMethodRunresult(e.getMessage());
						met.setMethodRunstatus("" + 500);
					}
					break;
				}
				case "PUT": {
					break;
				}
				case "DELETE": {
					break;
				}
				default: {
					met.setMethodRunstatus("错误");
					met.setMethodRunresult("未知的请求类型");
					break;
				}
				}
				long end = System.currentTimeMillis();
				met.setMethodRuntime(end - start + "毫秒");
			}
		}
		return mets;
	}
}
